package com.yuyunbo.es.restclient.autoconfigure;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yuyunbo.es.restclient.EsModel;
import com.yuyunbo.es.restclient.constants.EsConstants;
import com.yuyunbo.es.restclient.query.*;
import com.yuyunbo.es.restclient.util.AnnotationUtil;
import com.yuyunbo.es.restclient.util.EsException;
import com.yuyunbo.es.restclient.util.MapperUtils;
import com.yuyunbo.es.restclient.vo.EsScrollQueryResponse;
import com.yuyunbo.es.restclient.vo.PageBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.InitializingBean;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: yuyunbo-1154363414@qq.com
 * @Date: 2018/12/1 11:23
 * @Description:
 */
@Slf4j
public class EsRestClient implements InitializingBean {
    private static final String SPLIT = "/";
    private static final String ALL_INDEX = "*";
    private static final String SPLIT_H = "-";
    private static final String SPLIT_N = "\n";
    private static final String ERRORS = "errors";
    private int MAX_SIZE;
    private static final int MAX_SERACH_LENGTH = 10000;
    private static final Map<String, String> queryEmptyParams = new ConcurrentHashMap<>();
    private int connectTimeout;
    private int maxRetryTimeoutMillis;
    private static int esPortInt = 9900;
    private String esNodes;
    private String esPort;
    private RestClient restClient;

    public EsRestClient(String esNodes, String esPort, int connectTimeout, int maxRetryTimeoutMillis, int maxSize) {
        this.esNodes = esNodes;
        this.esPort = esPort;
        this.connectTimeout = connectTimeout;
        this.maxRetryTimeoutMillis = maxRetryTimeoutMillis;
        this.MAX_SIZE = maxSize;
    }

    @Override
    public void afterPropertiesSet() {
        initEsClient();
    }

    /**
     * client初始化
     */
    private void initEsClient() {
        log.info("===EsClient Init Start===,esNodes:{}", esNodes);
        if (null != restClient) {
            cleanUp();
        }
        try {
            String[] esNodeArray = this.esNodes.split(",");
            esPortInt = Integer.parseInt(esPort);
            List nodes = new ArrayList<HttpHost>();
            HttpHost httpHost = null;
            for (String esNode : esNodeArray) {
                httpHost = new HttpHost(esNode, esPortInt, EsConstants.HTTP_KEY);
                nodes.add(httpHost);
            }
            RestClientBuilder builder = RestClient.builder((HttpHost[]) nodes.toArray(new HttpHost[nodes.size()]));
            builder.setRequestConfigCallback((requestConfigBuilder) -> {
                requestConfigBuilder.setConnectTimeout(connectTimeout);
                return requestConfigBuilder;
            });
            builder.setMaxRetryTimeoutMillis(maxRetryTimeoutMillis);
            restClient = builder.build();
            log.info("===EsClient Init End===");
        } catch (Exception e) {
            log.error("===EsClient Init Error===", e);
        }
    }

    /**
     * 批量添加数据
     *
     * @param esModel
     * @param <T>
     */
    public <T> void batchPutToEsList(EsModel<T> esModel) {
        Response response = null;
        String bulkBoday = getBulkBoday(esModel);
        checkSize(bulkBoday);
        try (NStringEntity entity = new NStringEntity(bulkBoday, ContentType.APPLICATION_JSON)) {
            response = restClient.performRequest(HttpPut.METHOD_NAME, EsConstants.BULK_KEY, queryEmptyParams, entity);
            String responseStr = getResponseStr(response.getEntity());
            ObjectMapper mapper = MapperUtils.getInstance();
            JsonNode jsonObject = mapper.readTree(responseStr);
            if (jsonObject.get(ERRORS) != null && Boolean.valueOf(jsonObject.get(ERRORS).toString())) {
                log.error("ES 保存数据到对应的索引,类型出现异常={}", responseStr);
                throw new EsException("ES 保存数据到对应的索引,类型出现异常,查下看日志");
            }
        } catch (IOException e) {
            log.error("ES 保存数据到对应的索引,类型出现异常={}", e);
            throw new EsException("ES 保存数据到对应的索引,类型出现异常");
        }
    }

    /**
     * 封装批量提交的，请求体信息
     *
     * @param esModel
     * @param <T>
     * @return
     */
    private <T> String getBulkBoday(EsModel<T> esModel) {
        List<T> jsondata = esModel.getListData();
        StringBuilder sBuffer = new StringBuilder();
        Map<String, Map<String, String>> esBitchCreateHead = new HashMap<>();
        for (int i = 0; i < jsondata.size(); i++) {
            getEsBitchCreateHead(esBitchCreateHead, esModel, jsondata.get(i));
            sBuffer = sBuffer.append(MapperUtils.mapToJson(esBitchCreateHead)).append(SPLIT_N);
            sBuffer = sBuffer.append(MapperUtils.obj2json(jsondata.get(i))).append(SPLIT_N);
        }
        String bulkBodayStr = sBuffer.toString();
        return bulkBodayStr;
    }

    /**
     * 批量提交 封装批量提交抬头
     *
     * @param esBitchCreateHead
     * @param esModel
     * @param <T>
     */
    private <T> void getEsBitchCreateHead(Map<String, Map<String, String>> esBitchCreateHead, EsModel<T> esModel, T t) {
        Map<String, String> createHead = new HashMap<>();
        if (esModel.isMonthIndex()) {
            createHead.put(EsConstants.INDEX_KEY, esModel.getEsIndex().concat(SPLIT_H).concat(getYMStr(t)));
        } else {
            createHead.put(EsConstants.INDEX_KEY, esModel.getEsIndex());
        }
        createHead.put(EsConstants.TYPE_KEY, esModel.getEsType());
        createHead.put(EsConstants.ID_KEY, getPkey(t));
        esBitchCreateHead.put(EsConstants.CREATE_OR_KEY, createHead);
    }

    private <T> String getPkey(T t) {
        String value = AnnotationUtil.getESPKeyColumnValue(t);
        if (StringUtils.isEmpty(value)) {
            throw new EsException("请为对象配置ES主键,注入注解PKey并且赋值");
        }
        return value;
    }

    private <T> String getYMStr(T t) {
        String value = AnnotationUtil.getMonthKeyColumnValue(t);
        if (StringUtils.isEmpty(value)) {
            throw new EsException("请为对象配置月份索引注解,注入注解EsMonthKey");
        }
        return value.substring(0, 7).replaceAll("-", "");
    }

    /**
     * 单个提交数据
     *
     * @param esModel
     * @param <T>
     */
    public <T> void putToEs(EsModel<T> esModel) {
        String jsonStr = MapperUtils.obj2json(esModel.getData());
        if (log.isInfoEnabled()) {
            log.info("单个提交数据={}", jsonStr);
        }
        Response response = null;
        String esPKeyValue = getPkey(esModel.getData());
        if (StringUtils.isEmpty(esPKeyValue)) {
            throw new EsException("单个提交主键ID 不能为空 不能为空");
        }
        esModel.setDocId(esPKeyValue);
        try (NStringEntity entity = new NStringEntity(jsonStr, ContentType.APPLICATION_JSON)) {
            response = restClient.performRequest(HttpPut.METHOD_NAME, getUriStrForInsert(esModel).concat(esModel.getDocId()), queryEmptyParams, entity);
            String responseStr = getResponseStr(response.getEntity());
            ObjectMapper mapper = MapperUtils.getInstance();
            JsonNode jsonObject = mapper.readTree(responseStr);
            if (jsonObject.get(ERRORS) != null && Boolean.valueOf(jsonObject.get(ERRORS).toString())) {
                log.error("ES 保存数据到对应的索引,类型出现异常={}", responseStr);
                throw new EsException("ES 保存数据到对应的索引,类型出现异常,查下看日志");
            }
        } catch (IOException e) {
            log.error("ES 保存数据到对应的索引,类型出现异常", e);
            throw new EsException("ES 保存数据到对应的索引,类型出现异常");
        }
    }

    /**
     * 分页查询数据
     *
     * @param esModel
     * @param requiredType
     * @param <T>
     * @return
     */
    public <T> PageBean<T> queryPage(EsModel<T> esModel, Class<T> requiredType) {
        PageBean<T> pageBean = new PageBean<>();
        int currentPage = esModel.getPage();
        int size = esModel.getPageSize();
        String queryParamsStr = getHttpGetBoday(esModel);
        if (log.isInfoEnabled()) {
            log.info("es分页查入参={}", queryParamsStr);
        }
        try (NStringEntity entity = new NStringEntity(queryParamsStr, ContentType.APPLICATION_JSON)) {
            Response response = restClient.performRequest(HttpGet.METHOD_NAME, getUriStr(esModel).concat(EsConstants.SERACHPAGE_KEY), queryEmptyParams, entity);
            String readContent = getResponseStr(response.getEntity());
            ObjectMapper mapper = MapperUtils.getInstance();
            JsonNode jsonObject = mapper.readTree(readContent);
            JsonNode hitsJSON = mapper.readTree(jsonObject.get(EsConstants.HITS_KEY).toString());
            int total = Integer.valueOf(hitsJSON.get(EsConstants.TOTAL_KEY).toString());
            List<T> list = new ArrayList<>();
            Iterator<JsonNode> iterator = hitsJSON.get(EsConstants.HITS_KEY).elements();
            while (iterator.hasNext()) {
                JsonNode sourceJson = iterator.next();
                T objectResourceForES = MapperUtils.json2pojo(sourceJson.get(EsConstants.SOURCE_KEY).toString(), requiredType);
                list.add(objectResourceForES);
            }
            pageBean.setDatas(list);
            pageBean.setTotalCount(total);
            pageBean.setPageSize(size);
            pageBean.setTotalPages(getTotalPage(total, size));
            pageBean.setCurrentPage(currentPage);
            pageBean.setPageSize(size);
        } catch (IOException e) {
            log.error("ES分页查询异常", e);
            throw new EsException("ES分页查询异常");
        }
        return pageBean;
    }

    private <T> String getHttpGetBoday(EsModel<T> esModel) {
        int currentPage = esModel.getPage();
        int size = esModel.getPageSize();
        int from = (currentPage - 1) * size;
        int count = MAX_SERACH_LENGTH;
        if (size + from > count) {
            throw new EsException("查询数据深度不能超过10000");
        }
        ObjectMapper mapper = MapperUtils.getInstance();
        ObjectNode queryJson = mapper.createObjectNode();
        queryJson.put(EsConstants.FROM_KEY, String.valueOf(from));
        queryJson.put(EsConstants.FROM_SIZE, String.valueOf(size));
        EsShouldListQuery esShouldListQuery = esModel.getEsShouldListQuery();
        ArrayNode jsonArray = mapper.createArrayNode();
        ArrayNode shouldJsonArray = mapper.createArrayNode();
        ObjectNode must = mapper.createObjectNode();
        if (esShouldListQuery != null && esShouldListQuery.getMatch() != null) {
            Map<String, List<String>> shouldQueryMatch = esShouldListQuery.getMatch();
            if (!shouldQueryMatch.isEmpty()) {
                ObjectNode match = mapper.createObjectNode();
                Iterator<Map.Entry<String, List<String>>> iterator = shouldQueryMatch.entrySet().iterator();
                String key = null;
                List<String> value = null;
                Map.Entry<String, List<String>> entry = null;
                while (iterator.hasNext()) {
                    entry = iterator.next();
                    key = entry.getKey();
                    value = entry.getValue();
                    if (CollectionUtils.isNotEmpty(value)) {
                        for (String shouldvalue : value) {
                            match.put(key, shouldvalue);
                            ObjectNode esShould = mapper.createObjectNode();
                            esShould.set(EsConstants.MATCH_KEY, match);
                            shouldJsonArray.add(esShould);
                        }
                    }
                }
                ObjectNode should = mapper.createObjectNode();
                should.set(EsConstants.SHOULD_KEY, shouldJsonArray);
                ObjectNode shouldBoolJson = mapper.createObjectNode();
                shouldBoolJson.set(EsConstants.BOOL_KEY, should);
                jsonArray.add(shouldBoolJson);
            }
        }
        EsMatchQuery esMatchQuery = esModel.getEsMatchQuery();
        if (esMatchQuery != null && esMatchQuery.getMatch() != null) {
            Map<String, String> matchQuery = esMatchQuery.getMatch();
            if (!matchQuery.isEmpty()) {
                ObjectNode match = mapper.createObjectNode();
                Iterator<Map.Entry<String, String>> iterator = matchQuery.entrySet().iterator();
                String key = null;
                String value = null;
                Map.Entry<String, String> entry = null;
                while (iterator.hasNext()) {
                    entry = iterator.next();
                    key = entry.getKey();
                    value = entry.getValue();
                    if (StringUtils.isNotEmpty(value)) {
                        match.put(key, value);
                        ObjectNode esMatch = mapper.createObjectNode();
                        esMatch.set(EsConstants.MATCH_KEY, match);
                        jsonArray.add(esMatch);
                    }
                }
            }
        }
        EsTermsQuery esTermsQuery = esModel.getEsTermsQuery();
        if (esTermsQuery != null && esTermsQuery.getTerms() != null) {
            Map<String, List<String>> termsQuery = esTermsQuery.getTerms();
            if (!termsQuery.isEmpty()) {
                ObjectNode terms = mapper.createObjectNode();
                Iterator<Map.Entry<String, List<String>>> iterator = termsQuery.entrySet().iterator();
                String key = null;
                List<String> value = null;
                Map.Entry<String, List<String>> entry = null;
                while (iterator.hasNext()) {
                    entry = iterator.next();
                    key = entry.getKey();
                    value = entry.getValue();
                    if (CollectionUtils.isNotEmpty(value)) {
                        ArrayNode arrayValue = mapper.createArrayNode();
                        for (String val : value) {
                            arrayValue.add(val);
                        }
                        terms.set(key, arrayValue);
                        ObjectNode termsQueryVo = mapper.createObjectNode();
                        termsQueryVo.set(EsConstants.TERMS_KEY, terms);
                        jsonArray.add(termsQueryVo);
                    }
                }
            }
        }
        List<EsRangeQuery> esRangeQueries = esModel.getRangList();
        if (CollectionUtils.isNotEmpty(esRangeQueries)) {
            for (EsRangeQuery esGmtCreateRange : esRangeQueries) {
                Map<String, Map<String, String>> rangeMap = esGmtCreateRange.getRange();
                Set<Map.Entry<String, Map<String, String>>> sortValue = rangeMap.entrySet();
                ObjectNode esSortObject = mapper.createObjectNode();
                for (Map.Entry<String, Map<String, String>> entry : sortValue) {
                    ObjectNode rangNode = mapper.createObjectNode();
                    Map<String, String> map = entry.getValue();
                    Set<Map.Entry<String, String>> mapKey = map.entrySet();
                    ArrayNode rangList = mapper.createArrayNode();
                    for (Map.Entry<String, String> rangEntry : mapKey) {
                        ObjectNode rangValueNode = mapper.createObjectNode();
                        rangValueNode.put(rangEntry.getKey(), rangEntry.getValue());
                        rangList.add(rangValueNode);
                    }
                    rangNode.set(entry.getKey(), rangList);
                    esSortObject.set(EsConstants.RANGE_KEY, rangNode);
                }
                jsonArray.add(esSortObject);
            }
        }
        must.set(EsConstants.MUST_KEY, jsonArray);
        ObjectNode boolJson = mapper.createObjectNode();
        boolJson.set(EsConstants.BOOL_KEY, must);
        ObjectNode filterJson = mapper.createObjectNode();
        filterJson.set(EsConstants.FILTER_KEY, boolJson);
        ObjectNode bool = mapper.createObjectNode();
        bool.set(EsConstants.BOOL_KEY, filterJson);
        queryJson.set(EsConstants.QUERY_KEY, bool);
        if (esModel.getSort() != null && !esModel.getSort().isEmpty()) {
            ArrayNode sortList = mapper.createArrayNode();
            for (Map<String, EsSort> sortMap : esModel.getSort()) {
                Set<Map.Entry<String, EsSort>> sortValue = sortMap.entrySet();
                ObjectNode esSortObject = mapper.createObjectNode();
                for (Map.Entry<String, EsSort> entry : sortValue) {
                    ObjectNode esSort = mapper.createObjectNode();
                    esSort.put(EsConstants.ORDER_KEY, String.valueOf(entry.getValue().getOrder()));
                    esSortObject.set(entry.getKey(), esSort);
                }
                sortList.add(esSortObject);
            }
            queryJson.set(EsConstants.SORT_KEY, sortList);
        }
        String queryParamsStr = queryJson.toString();
        return queryParamsStr;
    }

    public <T> List<T> queryList(EsModel<T> esModel, Class<T> requiredType) {
        List<T> list = new ArrayList<>();
        String queryParamsStr = getHttpGetBoday(esModel);
        if (log.isInfoEnabled()) {
            log.info("es queryList查入参={}", queryParamsStr);
        }
        try (NStringEntity entity = new NStringEntity(queryParamsStr, ContentType.APPLICATION_JSON)) {
            Response response = restClient.performRequest(HttpGet.METHOD_NAME, getUriStr(esModel).concat(EsConstants.SERACHPAGE_KEY), queryEmptyParams, entity);
            String readContent = getResponseStr(response.getEntity());
            ObjectMapper mapper = MapperUtils.getInstance();
            JsonNode jsonObject = mapper.readTree(readContent);
            JsonNode hitsJSON = mapper.readTree(jsonObject.get(EsConstants.HITS_KEY).toString());
            Iterator<JsonNode> iterator = hitsJSON.get(EsConstants.HITS_KEY).elements();
            getListByIterator(iterator, list, requiredType);
        } catch (IOException e) {
            log.error("es查询List异常", e);
            throw new EsException("es查询List异常");
        }
        return list;
    }

    /**
     * 根据相应条件统计,对应相应的总数
     *
     * @param esModel
     * @param <T>
     * @return
     */
    public <T> int queryCount(EsModel<T> esModel) {
        int total = 0;
        esModel.setPage(0);
        esModel.setPageSize(1);
        String queryParamsStr = getHttpGetBoday(esModel);
        if (log.isInfoEnabled()) {
            log.info("es queryCount查入参={}", queryParamsStr);
        }
        try (NStringEntity entity = new NStringEntity(queryParamsStr, ContentType.APPLICATION_JSON)) {
            Response response = restClient.performRequest(HttpGet.METHOD_NAME, getUriStr(esModel).concat(EsConstants.SERACHPAGE_KEY), queryEmptyParams, entity);
            String readContent = getResponseStr(response.getEntity());
            ObjectMapper mapper = MapperUtils.getInstance();
            JsonNode jsonObject = mapper.readTree(readContent);
            JsonNode hitsJSON = mapper.readTree(jsonObject.get(EsConstants.HITS_KEY).toString());
            total = Integer.valueOf(hitsJSON.get(EsConstants.TOTAL_KEY).toString());
        } catch (IOException e) {
            log.error("es统计数据总数", e);
            throw new EsException("es统计数据总数");
        }
        return total;
    }

    public <T> EsScrollQueryResponse openScrollSearch(EsModel<T> esModel, int aliveSeconds, Class<T> requiredType) {
        NStringEntity entity = null;
        EsScrollQueryResponse<T> scrollQueryResponse;
        try {
            String queryParamsStr = getHttpGetBoday(esModel);
            if (log.isInfoEnabled()) {
                log.info("es queryList查入参={}", queryParamsStr);
            }
            entity = new NStringEntity(queryParamsStr, ContentType.APPLICATION_JSON);
            String endpoint = getUriStr(esModel).concat("_search?scroll=" + aliveSeconds + "s");
            Response response = restClient.performRequest(HttpGet.METHOD_NAME, endpoint, queryEmptyParams, entity);
            scrollQueryResponse = parseScrollQueryResultFromEsResponse(response, requiredType);
        } catch (IOException e) {
            log.error("es查询List异常", e);
            throw new EsException("es查询List异常");
        } finally {
            if (entity != null) {
                entity.close();
            }
        }
        return scrollQueryResponse;
    }

    public <T> EsScrollQueryResponse<T> searchByScrollId(String scrollId, int aliveSeconds, Class<T> requiredType) {
        NStringEntity entity = null;
        EsScrollQueryResponse<T> scrollQueryResponse;
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("scroll", aliveSeconds + "s");
            params.put("scroll_id", scrollId);
            String queryParamsStr = MapperUtils.mapToJson(params);
            if (log.isInfoEnabled()) {
                log.info("es queryList查入参={}", queryParamsStr);
            }
            entity = new NStringEntity(queryParamsStr, ContentType.APPLICATION_JSON);
            String endpoint = "/_search/scroll";
            Response response = restClient.performRequest(HttpPost.METHOD_NAME, endpoint, queryEmptyParams, entity);
            scrollQueryResponse = parseScrollQueryResultFromEsResponse(response, requiredType);
        } catch (IOException e) {
            log.error("es查询List异常", e);
            throw new EsException("es查询List异常");
        } finally {
            if (entity != null) {
                entity.close();
            }
        }
        return scrollQueryResponse;
    }

    private <T> EsScrollQueryResponse<T> parseScrollQueryResultFromEsResponse(Response response, Class<T> requiredType) {
        List<T> list = new ArrayList<>();
        String readContent = getResponseStr(response.getEntity());
        ObjectMapper mapper = MapperUtils.getInstance();
        int total = 0;
        try {
            JsonNode jsonObject = mapper.readTree(readContent);
            JsonNode hitsJSON = mapper.readTree(jsonObject.get(EsConstants.HITS_KEY).toString());
            Iterator<JsonNode> iterator = hitsJSON.get(EsConstants.HITS_KEY).elements();
            String scrollId = jsonObject.get("_scroll_id").toString();
            total = Integer.valueOf(hitsJSON.get(EsConstants.TOTAL_KEY).toString());
            getListByIterator(iterator, list, requiredType);
            return new EsScrollQueryResponse<>(list, total, scrollId);
        } catch (IOException e) {
            log.error("es查询List异常", e);
            throw new EsException("es查询List异常");
        }
    }

    private <T> void getListByIterator(Iterator<JsonNode> iterator, List<T> list, Class<T> requiredType) {
        while (iterator.hasNext()) {
            JsonNode sourceJson = iterator.next();
            T objectResourceForES = null;
            try {
                objectResourceForES = MapperUtils.json2pojo(sourceJson.get(EsConstants.SOURCE_KEY).toString(), requiredType);
            } catch (Exception e) {
                log.error("es查询List异常", e);
                throw new EsException("es查询List异常");
            }
            list.add(objectResourceForES);
        }
    }

    public void cleanUp() {
        try {
            if (restClient != null) {
                restClient.close();
            }
        } catch (IOException e) {
            log.error("EsClient clean up error", e);
        } finally {
            restClient = null;
        }
    }

    private void checkSize(String pramas) {
        if (StringUtils.isNotBlank(pramas)) {
            int size = pramas.getBytes().length / 1024 / 1024;
            if (size > MAX_SIZE) {
                throw new EsException("上传ES数据大小大于限定值,10M");
            }
        }
    }

    private String getUriStrForInsert(EsModel esModel) {
        String index = esModel.getEsIndex();
        String type = esModel.getEsType();
        if (!esModel.isMonthIndex()) {
            return SPLIT.concat(index).concat(SPLIT).concat(type).concat(SPLIT);
        } else {
            return SPLIT.concat(index).concat(SPLIT_H).concat(getYMStr(esModel.getData())).concat(SPLIT).concat(type).concat(SPLIT);
        }
    }


    private String getUriStr(EsModel esModel) {
        String index = esModel.getEsIndex();
        String type = esModel.getEsType();
        if (!esModel.isMonthIndex()) {
            return SPLIT.concat(index).concat(SPLIT).concat(type).concat(SPLIT);
        } else {
            return SPLIT.concat(index).concat(SPLIT_H).concat(ALL_INDEX).concat(SPLIT).concat(type).concat(SPLIT);
        }
    }

    private String getResponseStr(HttpEntity entity) {
        try {
            return EntityUtils.toString(entity);
        } catch (IOException e) {
            log.error("获取ES响应返回数据异常", e);
            throw new EsException("获取ES响应返回数据异常");
        }
    }

    private int getTotalPage(Integer count, Integer pageSize) {
        return count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
    }
}
